/* 
 * WindowMgr.cs
 * Part of Gamadus Engine. Visit www.gamadus.de.vu!
 * 
 * [DONE] Commenting finished.
 */
 
using System;
using System.Drawing;
 
using OpenTK;
using OpenTK.OpenGL;
using OpenTK.OpenGL.Enums;
using OpenTK.Fonts;
using OpenTK.Math;
using OpenTK.Input;
using OpenTK.Platform;

namespace Gamadus.Engine
{
	/// <summary>
	/// Holds the game window and provides methods to change it
	/// </summary>
	public class WindowMgr : SingletonManager<WindowMgr>
	{
		private GameWindow Window;
		
		/// <summary>
		/// Inits the Manager. Call before starting main loop.
		/// </summary>
		public void Init()
		{
			fullscreen = (bool)Engine.Instance.GameSettings[Setting.StartFullScreen];
			//TODO: Change to lower size when using OpenTK 0.9.1
			Window = new GameWindow(new DisplayMode(800,600,32,0,fullscreen),title);
			Window.Keyboard.KeyDown += InputMgr.Instance.Events_KeyboardDown;
			Window.Keyboard.KeyUp += InputMgr.Instance.Events_KeyboardUp;
			Window.Mouse.ButtonDown += InputMgr.Instance.Events_MouseDown;
			Window.Mouse.ButtonUp += InputMgr.Instance.Events_MouseUp;
			Window.Load += OnWindowLoad;
			Window.Resize += OnWindowResize;
			Window.RenderFrame += OnWindowRender;
		}
		
		
		private string title = "Gamadus Engine";
		
		/// <summary>
		/// Gets and sets the window title
		/// </summary>
		public string Title
		{
			get
			{
				return title;
			}
			set
			{
				if(Window != null)
				{
					Window.Title = value;
				}
				title = value;
			}
		}
		
		/// <summary>
		/// Gets the current and sets the wanted Fps
		/// </summary>
		public int Fps
		{
			get
			{
				return (int)Window.RenderFrequency;
			}
			set
			{
				Window.TargetRenderFrequency = value;
			}
		}
		
		/// <summary>
		/// Gets the current mouse position
		/// </summary>
		public Point MousePosition
		{
			get
			{
				return Window.Mouse.Position;
			}
		}
		
		/// <summary>
		/// Returns true if the window has been created
		/// </summary>
		public bool HasWindow
		{
			get
			{
				return (WindowMgr.Instance.Window != null);
			}
		}
		
		/// <summary>
		/// Changes the video resolution and fullscreen
		/// </summary>
		/// <param name="width">The new window width</param>
		/// <param name="height">The new window height</param>
		public void ChangeVideoMode(int width, int height)
		{
			//TODO: Add when using OpenTK 0.9.1
			//Window.Width = width;
			//Window.Height = height;
			//Window.Fullscreen = fullscreen;
		}
		
		/// <summary>
		/// Starts the game loop.
		/// Call this after initing alls the managers and going to the first room.
		/// </summary>
		public void Run()
		{
			Window.Run(0.0, 30.0);
		}
		                                
		private bool fullscreen;
		
		/// <summary>
		/// Gets and sets whether the game is in fullscreen mode.
		/// </summary>
		public bool Fullscreen
		{
			get
			{
				return fullscreen;
			}
			set
			{
				if(value != fullscreen)
				{
					fullscreen = value;
					ChangeVideoMode(RoomMgr.Instance.CurrentRoom.width, RoomMgr.Instance.CurrentRoom.height);
				}
			}
		}
		
		protected void OnWindowLoad(GameWindow sender, EventArgs e)
		{
			GL.ClearColor(RoomMgr.Instance.CurrentRoom.bgcolor);
            GL.Disable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Texture2d);
            GL.Enable(EnableCap.Blend);
            GL.Enable(EnableCap.AlphaTest);
            
            
            
		}
		
		protected void OnWindowResize(object sender, ResizeEventArgs e)
		{
			GL.Viewport(0, 0, Window.Width, Window.Height);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0.0,Window.Width, Window.Height,0.0,-1.0,1.0);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
		}
		
		protected void OnWindowRender(GameWindow sender, RenderFrameEventArgs e)
		{
			GL.Clear(ClearBufferMask.ColorBufferBit);
            GL.LoadIdentity();   
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha,BlendingFactorDest.OneMinusSrcAlpha);   
            RoomMgr.Instance.CurrentRoom.RoomStep();	
            Window.SwapBuffers();       
            InputMgr.Instance.UpdateKeys();
            Window.Title = "FPS: "+Math.Round(Window.RenderFrequency,2);
		}
		
		/// <summary>
		/// Exits the engine.
		/// </summary>
		public void Exit()
		{
			//TODO: Call the game-end events
			Window.Exit();
		}
	}
}
